package wrappers

import (
	"context"
	"github.com/afex/hystrix-go/hystrix"
	"github.com/micro/go-micro/client"
	"goMicro/day05/client/services"
	"strconv"
)

type ProdWrapper struct {
	client.Client
}

func (this *ProdWrapper) Call(ctx context.Context, req client.Request, rsp interface{}, opts ...client.CallOption) error {
	cndName := req.Service() + "." + req.Endpoint()
	//第一步 配置hystrix config
	configA := hystrix.CommandConfig{
		Timeout: 2000, //超时降级
		//熔断
		RequestVolumeThreshold: 2,
		ErrorPercentThreshold:  50, //表示是20%
		SleepWindow:            5000,
	}
	//第二部配置command
	hystrix.ConfigureCommand(cndName, configA)
	// 第三步
	err := hystrix.Do(cndName, func() error {
		return this.Client.Call(ctx, req, rsp) // 待用父类的方法
	}, func(e error) error {
		defauyltData(rsp)
		return nil
	})

	return err
}
func NewProdWrapper(c client.Client) client.Client {
	return &ProdWrapper{c}
}

// 降级函数 通用处理
func defauyltData(rsp interface{}) {
	switch t := rsp.(type) {
	case *services.ProdListResponse:
		defaultProds(rsp)
	case *services.ProdDetailResponse:
		t.Data = newProd(10, "降级商品")
	}
}

func defaultProds(rsp interface{}) {
	models := make([]*services.ProdModel, 0)
	var i int32
	for i = 0; i < 5; i++ {
		models = append(models, newProd(200+i, "商品"+strconv.Itoa(200+int(i))))
	}
	result := rsp.(*services.ProdListResponse)
	result.Data = models

}

//测试方法
func newProd(id int32, pname string) *services.ProdModel {
	return &services.ProdModel{ProdID: id, ProdName: pname}
}
